Case example 1 Raw Data
Table
penguins = read.csv("https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w03/w03-penguins.csv")
penguins.new <- na.omit(penguins)
penguins.new =
filter(penguins.new, (species == "Adelie" | species == "Gentoo")
& (island == "Biscoe" | island == "Torgersen" )
& (5000 > body_mass_g & body_mass_g > 3500) )
penguins.new$BMI <- penguins.new$body_mass_g/(4000)
penguins.new <- subset(penguins.new, select = -c(X,body_mass_g,sex,year ))
Descriptive Statistic
& Variables Relationship
- flip : Penguins flipper length (mm)
- bill : Penguins bill length (mm)
- BMI: Penguins body mass / 4000 (grams)
flip = summary(penguins.new$flipper_length_mm )
bill = summary(penguins.new$bill_length_mm )
BMI = summary(penguins.new$BMI )
list(flip = flip, bill = bill, BMI=BMI)
$flip
Min. 1st Qu. Median Mean 3rd Qu. Max.
180.0 191.0 200.0 201.5 212.0 222.0
$bill
Min. 1st Qu. Median Mean 3rd Qu. Max.
33.50 39.55 42.70 42.46 45.75 49.60
$BMI
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.8875 0.9719 1.0750 1.0697 1.1750 1.2437
pen <- c("flipper_length_mm", "bill_length_mm", "BMI")
DB <- penguins.new[pen]
pairs(DB)

- flipper_length_mm : Penguins flipper length (mm)
- bill_length_mm : Penguins bill length (mm)
- BMI: Penguins body mass / 4000 (grams)
From the above figure, it is positive linear relationship between
flipper_length_mm and BMI. Moreover, it is positive linear relationship
between bill_length_mm and BMI.
The relationship
between Bill legnth and Flipper length across 2 species
pg.img <- "https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w03/img2/penguin.jpeg"
my.pg <- readJPEG(getURLContent(pg.img))
raster.pg <- as.raster(my.pg)
# Use the code in the precious section
Bill.length = penguins.new$bill_length_mm
Flipper.length = as.numeric(penguins.new$flipper_length_mm)
size.body = as.numeric(penguins.new$BMI)
species = penguins.new$species
## identifying the ID
Adelie.id = which(species=="Adelie") # value are case sensitive!
Gentoo.id = which(species=="Gentoo")
## making an empty plot: type = "n" ==> no point
plot(Bill.length, Flipper.length, main = "Bill legnth vs Flipper legnth across 2 species", type = "n" , xlab = "Bill legnth (mm)", ylab = "Flipper Length (mm)")
points(Bill.length[Adelie.id], Flipper.length[Adelie.id],
pch = 19, col = "purple", cex = size.body[Adelie.id])
points(Bill.length[Gentoo.id], Flipper.length[Gentoo.id],
pch = 19, col = "navy", cex = size.body[Gentoo.id])
legend("topleft", c("Adelie", "Gentoo"),
col=c("purple", "navy"),
pch=c(19, 19))
#rasterImage(raster.pg,57,190,60,220)
# plot a regression line
abline(lm(Flipper.length[Adelie.id]~Bill.length[Adelie.id]),col='purple')
abline(lm(Flipper.length[Gentoo.id]~Bill.length[Gentoo.id]),col='navy')

From above the figure, most Gentoo penguins have longer flipper and
longer bill than Adelie penguins. In addition, there is a positive
linear relationship between flipper length and bill length in both the
Gentoo and Adelie penguin studies.
Case example 2 Raw Data
Table
Data Preparation
There are 4 raw data available on the Github website, including
incomes file, life expectancy years file, countries total file and
population total file. In addition,incomes file, life expectancy years
file and population total file have to transpose data files (from wide
to long). Then, combine the four files into a final dataset by using
PROC SQL.
#read data files from GitHub
I.P.P = read.csv("https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w05/income_per_person.csv")
L.E.Y = read.csv("https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w05/life_expectancy_years.csv")
countrytot = read.csv("https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w05/countries_total.csv")
poptot = read.csv("https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w05/population_total.csv")
#transpose data from wide to long
IPPlong <- melt(setDT(I.P.P),value.name = "income", id.vars = c("geo"), variable.name = "year")
LEYlong <- melt(setDT(L.E.Y),value.name = "life_expectancy", id.vars = c("geo"), variable.name = "year")
poptotlong <- melt(setDT(poptot),value.name = "pop_size", id.vars = c("geo"), variable.name = "year")
## remove string X
IPPlong$year<-gsub("X","",as.character(IPPlong$year))
LEYlong$year<-gsub("X","",as.character(LEYlong$year))
poptotlong$year<-gsub("X","",as.character(poptotlong$year))
#merge Income Per Person and Life Expectancy in Years
LifeExpIncom <- merge(LEYlong, IPPlong, by = c("geo", "year"),
all = TRUE)
#Create database
con <- dbConnect(drv = SQLite(),
dbname = ":memory:")
#store sample data in database
dbWriteTable(conn = con,
name = "LEYlong",
value = LEYlong)
dbWriteTable(conn = con,
name = "IPPlong",
value = IPPlong)
dbWriteTable(conn = con,
name = "LifeExpIncom",
value = LifeExpIncom)
dbWriteTable(conn = con,
name = "countrytot",
value = countrytot)
dbWriteTable(conn = con,
name = "poptotlong",
value = poptotlong)
SELECT a.*, b.region
FROM LifeExpIncom AS A
LEFT JOIN countrytot AS B
ON A.geo = B.name;
#store sample data in database
dbWriteTable(conn = con,
name = "life2",
value = life2)
SELECT a.*, b.pop_size
FROM life2 AS A
LEFT JOIN poptotlong AS B
ON A.geo = B.geo AND A.year = B.year ;
# write final data to csv file
write.csv(x = final, file = "final.csv", row.names = FALSE)
# read final file
final = read.csv("https://raw.githubusercontent.com/GUANTSERN-KUO/webcv/main/w05/final.csv")
data2015 <- filter(final,year==2015) # create 2015data
data2015$size000 <- data2015$pop_size/20000000
Descriptive Study
Purpose & Variables Relationship
The study focus on the relationship between income and life
expectancy across region in 2015. Secondary understanding of the
relationship between income and life expectancy over year in different
regions. There are 7 variables in final dataset.
- geo : geography
- pop_size : population size
- size000 : equivalent ratio to population size
The below is the data table for 2015.
summary(data2015)
geo year life_expectancy income
Length:193 Min. :2015 Min. :49.60 Min. : 623
Class :character 1st Qu.:2015 1st Qu.:66.05 1st Qu.: 3290
Mode :character Median :2015 Median :73.30 Median : 11000
Mean :2015 Mean :71.93 Mean : 17433
3rd Qu.:2015 3rd Qu.:77.50 3rd Qu.: 24100
Max. :2015 Max. :83.80 Max. :120000
NA's :6
region pop_size size000
Length:193 Min. :1.100e+04 Min. : 0.00055
Class :character 1st Qu.:1.990e+06 1st Qu.: 0.09950
Mode :character Median :8.550e+06 Median : 0.42750
Mean :3.807e+07 Mean : 1.90340
3rd Qu.:2.760e+07 3rd Qu.: 1.38000
Max. :1.400e+09 Max. :70.00000
People with a maximum income of 120000 and a minimum income of 623 in
2015. Also, in 2015, people’s life expectancy index ranged from a high
of 83.8 to a low of 49.6.
The Distribuition of
Region in 2015
Asia has the highest percentage of the world’s population (28.5%),
with a total of 51 countries. Oceania has the lowest percentage of the
world’s population (7.26%), with a total of 13 countries.
piedata <- filter(data2015,!is.na(region))
piedataf = data.frame(cate =as.vector(unique(piedata$region)),
freq = as.vector(table(piedata$region)))
# define a color vector
colors <- c('rgb(211,94,96)', 'rgb(128,133,133)', 'rgb(144,103,167)')
# make a pie chart
plot_ly(piedataf,
labels = ~cate,
values = ~freq,
type = 'pie',
textposition = 'inside',
textinfo = 'label + percent',
insidetextfont = list(color = '#FFFFFF'),
#hoverinfo = 'text',
marker = list(colors = colors,
line = list(color = '#FFFFFF', width = 1)),
#The 'pull' attribute can also be used to create space between the sectors
showlegend = TRUE) %>%
layout(title = 'Distribution of Region in 2015',
xaxis = list(showgrid = FALSE, zeroline = FALSE,
showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE,
showticklabels = FALSE),
## margin of the plot
margin = list(
b = 50,
l = 100,
t = 120,
r = 50
))
The relationship
between Income and Life Expectancy across Region in 2015
Most people in the European region have higher incomes and higher
levels of life expectancy. And most people in the African region have
lower incomes and lower levels of life expectancy.
plot_ly(
data = data2015,
x = ~income, # Horizontal axis
y = ~life_expectancy, # Vertical axis
color = ~factor(region), # must be a numeric factor
#text = ~Species,
text = ~paste("country name: ", geo,
"<br>population size: ", pop_size,
"<br>region: ", region),
# Show the species in the hover text
## using the following hovertemplate() to add the information of the
## Two numerical variables to the hover text.
### Use the following hover template to display more information
hovertemplate = paste('<i><b>life expectancy<b></i>: %{y}',
'<br><b>income</b>: %{x}',
'<br><b>%{text}</b>'),
alpha = 0.6,
marker = list(size = ~size000, sizeref = .05, sizemode = 'area' ),
type = "scatter",
mode = "markers",
## graphic size
width = 700,
height = 500) %>%
layout(
### Title
title =list(text = "Income vs Life Expectancy in 2015",
font = list(family = "Times New Roman", # HTML font family
size = 18,
color = "red")),
### legend
legend = list(title = list(text = 'region',
font = list(family = "Courier New",
size = 14,
color = "green")),
bgcolor = "ivory",
bordercolor = "navy",
groupclick = "togglegroup", # one of "toggleitem" AND "togglegroup".
orientation = "v" # Sets the orientation of the legend.
),
## margin of the plot
margin = list(
b = 100,
l = 100,
t = 50,
r = 50
),
## Background
plot_bgcolor ='#f7f7f7',
## Axes labels
xaxis = list(
title=list(text = 'Income',
font = list(family = 'Arial')),
zerolinecolor = 'red',
zerolinewidth = 2,
gridcolor = 'white'),
yaxis = list(
title=list(text = 'Life Expectancy',
font = list(family = 'Arial')),
zerolinecolor = 'purple',
zerolinewidth = 2,
gridcolor = 'white'),
## annotations
annotations = list(
x = 0.5, # between 0 and 1. 0 = left, 1 = right
y = 1.5, # between 0 and 1, 0 = bottom, 1 = top
font = list(size = 12,
color = "darkred"),
text = "The point size is proportional to the population size",
xref = "paper", # "container" spans the entire `width` of the
# lot. "paper" refers to the width of the
# plotting area only. yref = "paper",
# same as xref.
xanchor = "center", # horizontal alignment with respect to its x position
yanchor = "bottom", # similar to xanchor
showarrow = FALSE)
)
The relationship
between Income and Life Expectancy across Region over the years
The life expectancy of people in the all regions has increased with
each passing year. In 1800, most of Europe had a higher level of life
expectancy. However, in 2018, higher levels of life expectancy may come
from multiple regional of country. As can be seen from the figure, there
is a positive linear relationship between income and levels of life
expectancy across regions.
pal.IBM <- c("#332288", "#117733", "#0072B2","#D55E00", "#882255")
pal.IBM <- setNames(pal.IBM, c("Asia", "Europe", "Africa", "Americas", "Oceania"))
df <- filter(final,!is.na(region))
#df <- final
fig <- df %>%
plot_ly(
x = ~income,
y = ~life_expectancy,
size = ~(2*log(pop_size)-11)^2,
color = ~region,
colors = pal.IBM, # custom colors
#marker = list(size = ~(log(pop)-10), sizemode = 'area'),
frame = ~year, # the time variable to
# to display in the hover
text = ~paste("Country:", geo,
"<br>Region:", region,
"<br>Year:", year,
"<br>LifeExp:", life_expectancy,
"<br>Pop:", pop_size),
hoverinfo = "text",
type = 'scatter',
mode = 'markers'
)
fig <- fig %>% layout(
xaxis = list(
type = "log"
),
title =list(text = "Income vs Life Expectancy over the years",
font = list(family = "Times New Roman", # HTML font family
size = 18,
color = "red")),
xaxis = list(
title=list(text = 'Income',
font = list(family = 'Arial')),
zerolinecolor = 'red',
zerolinewidth = 2,
gridcolor = 'white'),
yaxis = list(
title=list(text = 'Life Expectancy',
font = list(family = 'Arial')),
zerolinecolor = 'purple',
zerolinewidth = 2,
gridcolor = 'white')
)
fig
LS0tDQp0aXRsZTogIlByZXNlbnRhdGlvbiBMaW5lYXIgUmVncmVzc2lvbiINCmF1dGhvcjogIkd1YW4gVHNlcm4gS3VvIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgdGhlbWU6IGx1bWVuDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KLyogVGFibGUgb2YgY29udGVudCAtIG5hdmlnYXRpb24gKi8NCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOmxpZ2h0Z3JheTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQogICAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6ICM3ODBjMGM7DQp9DQoNCg0KLyogVGl0bGUgZm9udHMgKi8NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogZGFya2JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogIGZvbnQtdmFyaWFudC1jYXBzOiBub3JtYWw7DQp9DQpoNC5hdXRob3IgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IGRhcmtibHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi8qIFNlY3Rpb24gaGVhZGVycyAqLw0KaDEgew0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMiB7DQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgDQogICAgZm9udC1zaXplOiAxNXB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsNCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogRGVjb3JhdGlvbiBvZiBoeXBlcmxpbmtzICAqLw0KDQovKiB1bnZpc2l0ZWQgbGluayAqLw0KYTpsaW5rIHsNCiAgY29sb3I6IGdyZWVuOw0KfQ0KDQovKiB2aXNpdGVkIGxpbmsgKi8NCmE6dmlzaXRlZCB7DQogIGNvbG9yOiBwdXJwbGU7DQp9DQoNCi8qIG1vdXNlIG92ZXIgbGluayAqLw0KYTpob3ZlciB7DQogIGNvbG9yOiByZWQ7DQp9DQoNCi8qIHNlbGVjdGVkIGxpbmsgKi8NCmE6YWN0aXZlIHsNCiAgY29sb3I6IHllbGxvdzsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImdhcG1pbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJnYXBtaW5kZXIiKQ0KICAgbGlicmFyeShnYXBtaW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHlyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCiAgIGxpYnJhcnkodGlkeXIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoImNvd3Bsb3QiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiY293cGxvdCIpDQogICBsaWJyYXJ5KGNvd3Bsb3QpDQp9DQppZiAoIXJlcXVpcmUoImxhdGV4MmV4cCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJsYXRleDJleHAiKQ0KICAgbGlicmFyeShsYXRleDJleHApDQp9DQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICAgbGlicmFyeShwbG90bHkpDQp9DQppZiAoIXJlcXVpcmUoImdhcG1pbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJnYXBtaW5kZXIiKQ0KICAgbGlicmFyeShnYXBtaW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoInBuZyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygicG5nIikgICAgICAgICAgICAgIyBJbnN0YWxsIHBuZyBwYWNrYWdlDQogICAgbGlicmFyeSgicG5nIikNCn0NCmlmICghcmVxdWlyZSgiUkN1cmwiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIlJDdXJsIikgICAgICAgICAgICAgIyBJbnN0YWxsIFJDdXJsIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJSQ3VybCIpDQp9DQppZiAoIXJlcXVpcmUoImNvbG91cnBpY2tlciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImNvbG91cnBpY2tlciIpDQp9DQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdnYW5pbWF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdpZnNraSIpDQp9DQppZiAoIXJlcXVpcmUoIm1hZ2ljayIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm1hZ2ljayIpDQp9DQppZiAoIXJlcXVpcmUoImdyRGV2aWNlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JEZXZpY2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyRGV2aWNlcyIpDQp9DQppZiAoIXJlcXVpcmUoImpwZWciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImpwZWciKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgianBlZyIpDQp9DQppZiAoIXJlcXVpcmUoIlZHQU0iKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIlZHQU0iKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiVkdBTSIpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIk1BU1MiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiTUFTUyIpDQp9DQppZiAoIXJlcXVpcmUoIm5uZXQiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIm5uZXQiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibm5ldCIpDQp9DQppZiAoIXJlcXVpcmUoImNsdXN0ZXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImNsdXN0ZXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiY2x1c3RlciIpDQp9DQppZiAoIXJlcXVpcmUoImRwbHlyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJkcGx5ciIpDQp9DQppZiAoIXJlcXVpcmUoIm9kYmMiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygib2RiYyIpDQogICBsaWJyYXJ5KG9kYmMpDQp9DQppZiAoIXJlcXVpcmUoIkRCSSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJEQkkiKQ0KICAgbGlicmFyeShEQkkpDQp9DQppZiAoIXJlcXVpcmUoIlJTUUxpdGUiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiUlNRTGl0ZSIpDQogICBsaWJyYXJ5KFJTUUxpdGUpDQp9DQoNCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmICghcmVxdWlyZSgiZGF0YS50YWJsZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJkYXRhLnRhYmxlIikNCiAgIGxpYnJhcnkoZGF0YS50YWJsZSkNCn0NCg0KDQojIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6XFxTVEE0OTBcXHcwNSIpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEpDQoNCmRiIDwtIGRiQ29ubmVjdChSU1FMaXRlOjpTUUxpdGUoKSwgZGJuYW1lID0gInNxbC5zcWxpdGUiKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGNvbm5lY3Rpb24gPSAiZGIiKQ0KDQoNCmBgYA0KDQoNCiMgSW50cm9kdWN0aW9uIA0KDQpMaW5lYXIgcmVncmVzc2lvbiBpcyBvbmUgb2YgdGhlIHNpbXBsZXN0IHByZWRpY3RpdmUgbW9kZWxpbmcgYWxnb3JpdGhtcyB0aGF0IGNhbiBwcmVkaWN0IHRoZSB2YWx1ZSBvZiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGJ5IGNvbnNpZGVyaW5nIG9ubHkgb25lIGluZGVwZW5kZW50IHZhcmlhYmxlLiBUaGUgdmFyaWFibGUgdG8gYmUgcHJlZGljdGVkIGlzIGNhbGxlZCB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLiBUaGUgdmFyaWFibGUgdXNlZCB0byBwcmVkaWN0IHRoZSB2YWx1ZSBvZiBhbm90aGVyIHZhcmlhYmxlIGlzIGNhbGxlZCB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUuDQoNCg0KDQojIERlZmluYXRpb24NCg0KTGluZWFyIHJlZ3Jlc3Npb24gaXMgYW4gYWxnb3JpdGhtIHRoYXQgc2hvd3MgYSBsaW5lYXIgcmVsYXRpb25zaGlwICAgIGJldHdlZW4gYW4gaW5kZXBlbmRlbnQgdmFyaWFibGUgYW5kIGEgZGVwZW5kZW50IHZhcmlhYmxlLg0KDQoNCmBgYHtyICxlY2hvID0gRkFMU0V9DQprbml0cjo6IGluY2x1ZGVfZ3JhcGhpY3MoImxpbi5naWYiKQ0KYGBgDQoNCg0KIyBNYXRoZW1hdGljYWwgRm9ybXVsYXMNCg0KWSBpcyBkZXBlbmRlbnQgdmFyaWFibGUNCs6yMCBpcyBiaWFzIHRlcm0NCs6yMSzOsjIsLi4uzrJuIGFyZSBjb2VmZmljaWVudA0KeDEseDIsLi4ueG4gYXJlIGluZGVwZW5kZW50IHZhcmlhYmxlDQrOtSBpcyByYW5kb20gZXJyb3INCg0KQW4gZXhhbXBsZSBvZiBpbmxpbmUgZXF1YXRpb24gJHk9XGJldGFfMCtcYmV0YV8xeF8xK1xjZG90cytcYmV0YV9reF9rK1xlcHNpbG9uJCwgd2hlcmUgJFxlcHNpbG9uIFxzaW0gTigwLCBcc2lnbWFeMikkLg0KDQojICBBc3N1bXB0aW9ucyBhc3NvY2lhdGVkIHdpdGggYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbA0KDQotIExpbmVhcml0eTogVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIFggYW5kIHRoZSBtZWFuIG9mIFkgaXMgbGluZWFyLg0KLSBIb21vc2NlZGFzdGljaXR5OiBUaGUgdmFyaWFuY2Ugb2YgcmVzaWR1YWwgaXMgdGhlIHNhbWUgZm9yIGFueSB2YWx1ZSBvZiBYLg0KLSBJbmRlcGVuZGVuY2U6IE9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgb2YgZWFjaCBvdGhlci4NCi0gTm9ybWFsaXR5OiBGb3IgYW55IGZpeGVkIHZhbHVlIG9mIFgsIFkgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCg0KDQojIENhc2UgZXhhbXBsZSAxIFJhdyBEYXRhIFRhYmxlICAgDQoNCmBgYHtyfQ0KcGVuZ3VpbnMgPSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0dVQU5UU0VSTi1LVU8vd2ViY3YvbWFpbi93MDMvdzAzLXBlbmd1aW5zLmNzdiIpDQoNCnBlbmd1aW5zLm5ldyA8LSBuYS5vbWl0KHBlbmd1aW5zKQ0KIA0KcGVuZ3VpbnMubmV3ID0gDQogIGZpbHRlcihwZW5ndWlucy5uZXcsIChzcGVjaWVzID09ICJBZGVsaWUiIHwgc3BlY2llcyA9PSAiR2VudG9vIikNCiAgICAgICAgICAgICYgKGlzbGFuZCA9PSAiQmlzY29lIiB8IGlzbGFuZCA9PSAiVG9yZ2Vyc2VuIiApIA0KICAgICAgICAgICAgJiAoNTAwMCA+IGJvZHlfbWFzc19nICYgYm9keV9tYXNzX2cgPiAzNTAwKSApDQoNCnBlbmd1aW5zLm5ldyRCTUkgPC0gcGVuZ3VpbnMubmV3JGJvZHlfbWFzc19nLyg0MDAwKQ0KDQpwZW5ndWlucy5uZXcgPC0gc3Vic2V0KHBlbmd1aW5zLm5ldywgc2VsZWN0ID0gLWMoWCxib2R5X21hc3NfZyxzZXgseWVhciApKQ0KDQpgYGAgDQogDQoNCg0KYGBge3IgZXZhbD1yZXF1aXJlTmFtZXNwYWNlKCJEVCIsIHF1aWV0bHk9VFJVRSksIGVjaG89RkFMU0V9DQpEVDo6ZGF0YXRhYmxlKChwZW5ndWlucy5uZXcpLCBmaWxsQ29udGFpbmVyID0gRkFMU0UsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSA2KSkNCg0KDQpgYGANCg0KIyMgRGVzY3JpcHRpdmUgU3RhdGlzdGljICYgVmFyaWFibGVzIFJlbGF0aW9uc2hpcCANCg0KLSBmbGlwIDogUGVuZ3VpbnMgZmxpcHBlciBsZW5ndGggKG1tKQ0KLSBiaWxsIDogUGVuZ3VpbnMgYmlsbCBsZW5ndGggKG1tKQ0KLSBCTUk6IFBlbmd1aW5zIGJvZHkgbWFzcyAvIDQwMDAgKGdyYW1zKQ0KDQoNCmBgYHtyfQ0KZmxpcCA9IHN1bW1hcnkocGVuZ3VpbnMubmV3JGZsaXBwZXJfbGVuZ3RoX21tICkNCg0KYmlsbCA9IHN1bW1hcnkocGVuZ3VpbnMubmV3JGJpbGxfbGVuZ3RoX21tICkNCkJNSSA9IHN1bW1hcnkocGVuZ3VpbnMubmV3JEJNSSApDQoNCg0KbGlzdChmbGlwID0gZmxpcCwgYmlsbCA9IGJpbGwsIEJNST1CTUkpDQoNCnBlbiA8LSBjKCJmbGlwcGVyX2xlbmd0aF9tbSIsICJiaWxsX2xlbmd0aF9tbSIsICJCTUkiKQ0KREIgPC0gcGVuZ3VpbnMubmV3W3Blbl0NCnBhaXJzKERCKQ0KYGBgDQoNCi0gZmxpcHBlcl9sZW5ndGhfbW0gOiBQZW5ndWlucyBmbGlwcGVyIGxlbmd0aCAobW0pDQotIGJpbGxfbGVuZ3RoX21tIDogUGVuZ3VpbnMgYmlsbCBsZW5ndGggKG1tKQ0KLSBCTUk6IFBlbmd1aW5zIGJvZHkgbWFzcyAvIDQwMDAgKGdyYW1zKQ0KDQpGcm9tIHRoZSBhYm92ZSBmaWd1cmUsIGl0IGlzIHBvc2l0aXZlIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBmbGlwcGVyX2xlbmd0aF9tbSBhbmQgQk1JLiBNb3Jlb3ZlciwgaXQgaXMgcG9zaXRpdmUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGJpbGxfbGVuZ3RoX21tIGFuZCBCTUkuIA0KDQojIyAgIFRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBCaWxsIGxlZ250aCBhbmQgRmxpcHBlciBsZW5ndGggYWNyb3NzIDIgc3BlY2llcw0KDQpgYGB7cn0NCg0KIA0KcGcuaW1nIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vR1VBTlRTRVJOLUtVTy93ZWJjdi9tYWluL3cwMy9pbWcyL3Blbmd1aW4uanBlZyINCm15LnBnIDwtIHJlYWRKUEVHKGdldFVSTENvbnRlbnQocGcuaW1nKSkNCnJhc3Rlci5wZyA8LSBhcy5yYXN0ZXIobXkucGcpDQoNCiMgVXNlIHRoZSBjb2RlIGluIHRoZSBwcmVjaW91cyBzZWN0aW9uDQpCaWxsLmxlbmd0aCA9IHBlbmd1aW5zLm5ldyRiaWxsX2xlbmd0aF9tbQ0KRmxpcHBlci5sZW5ndGggPSBhcy5udW1lcmljKHBlbmd1aW5zLm5ldyRmbGlwcGVyX2xlbmd0aF9tbSkNCnNpemUuYm9keSA9IGFzLm51bWVyaWMocGVuZ3VpbnMubmV3JEJNSSkNCg0Kc3BlY2llcyA9IHBlbmd1aW5zLm5ldyRzcGVjaWVzDQoNCiMjIGlkZW50aWZ5aW5nIHRoZSBJRCANCkFkZWxpZS5pZCA9IHdoaWNoKHNwZWNpZXM9PSJBZGVsaWUiKSAgIyB2YWx1ZSBhcmUgY2FzZSBzZW5zaXRpdmUhDQpHZW50b28uaWQgPSB3aGljaChzcGVjaWVzPT0iR2VudG9vIikNCg0KDQojIyBtYWtpbmcgYW4gZW1wdHkgcGxvdDogdHlwZSA9ICJuIiA9PT4gbm8gcG9pbnQNCnBsb3QoQmlsbC5sZW5ndGgsIEZsaXBwZXIubGVuZ3RoLCBtYWluID0gIkJpbGwgbGVnbnRoIHZzIEZsaXBwZXIgbGVnbnRoIGFjcm9zcyAyIHNwZWNpZXMiLCB0eXBlID0gIm4iICwgIHhsYWIgPSAiQmlsbCBsZWdudGggKG1tKSIsIHlsYWIgPSAiRmxpcHBlciBMZW5ndGggKG1tKSIpDQoNCnBvaW50cyhCaWxsLmxlbmd0aFtBZGVsaWUuaWRdLCBGbGlwcGVyLmxlbmd0aFtBZGVsaWUuaWRdLCANCiAgICAgICBwY2ggPSAxOSwgY29sID0gInB1cnBsZSIsIGNleCA9IHNpemUuYm9keVtBZGVsaWUuaWRdKQ0KDQpwb2ludHMoQmlsbC5sZW5ndGhbR2VudG9vLmlkXSwgRmxpcHBlci5sZW5ndGhbR2VudG9vLmlkXSwgDQogICAgICAgcGNoID0gMTksIGNvbCA9ICJuYXZ5IiwgY2V4ID0gc2l6ZS5ib2R5W0dlbnRvby5pZF0pDQoNCg0KbGVnZW5kKCJ0b3BsZWZ0IiwgYygiQWRlbGllIiwgIkdlbnRvbyIpLCANCiAgICAgICAgICAgICAgICAgIGNvbD1jKCJwdXJwbGUiLCAibmF2eSIpLA0KICAgICAgICAgICAgICAgICAgcGNoPWMoMTksIDE5KSkNCg0KI3Jhc3RlckltYWdlKHJhc3Rlci5wZyw1NywxOTAsNjAsMjIwKQ0KDQojIHBsb3QgYSByZWdyZXNzaW9uIGxpbmUgDQphYmxpbmUobG0oRmxpcHBlci5sZW5ndGhbQWRlbGllLmlkXX5CaWxsLmxlbmd0aFtBZGVsaWUuaWRdKSxjb2w9J3B1cnBsZScpIA0KDQphYmxpbmUobG0oRmxpcHBlci5sZW5ndGhbR2VudG9vLmlkXX5CaWxsLmxlbmd0aFtHZW50b28uaWRdKSxjb2w9J25hdnknKSANCmBgYCANCg0KRnJvbSBhYm92ZSB0aGUgZmlndXJlLCBtb3N0IEdlbnRvbyBwZW5ndWlucyBoYXZlIGxvbmdlciBmbGlwcGVyIGFuZCBsb25nZXIgYmlsbCB0aGFuIEFkZWxpZSBwZW5ndWlucy4gSW4gYWRkaXRpb24sIHRoZXJlIGlzIGEgcG9zaXRpdmUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGZsaXBwZXIgbGVuZ3RoIGFuZCBiaWxsIGxlbmd0aCANCmluIGJvdGggdGhlIEdlbnRvbyBhbmQgQWRlbGllIHBlbmd1aW4gc3R1ZGllcy4NCiANCiANCiANCiMgQ2FzZSBleGFtcGxlIDIgUmF3IERhdGEgVGFibGUgDQoNCiMjIERhdGEgUHJlcGFyYXRpb24NCg0KDQpUaGVyZSBhcmUgNCByYXcgZGF0YSBhdmFpbGFibGUgb24gdGhlIEdpdGh1YiB3ZWJzaXRlLCBpbmNsdWRpbmcgaW5jb21lcyBmaWxlLCBsaWZlIGV4cGVjdGFuY3kgeWVhcnMgZmlsZSwgY291bnRyaWVzIHRvdGFsIGZpbGUgYW5kIHBvcHVsYXRpb24gdG90YWwgZmlsZS4gSW4gYWRkaXRpb24saW5jb21lcyBmaWxlLCBsaWZlIGV4cGVjdGFuY3kgeWVhcnMgZmlsZSBhbmQgcG9wdWxhdGlvbiB0b3RhbCBmaWxlIGhhdmUgdG8gdHJhbnNwb3NlIGRhdGEgZmlsZXMgKGZyb20gd2lkZSB0byBsb25nKS4gVGhlbiwgY29tYmluZSB0aGUgZm91ciBmaWxlcyBpbnRvIGEgZmluYWwgZGF0YXNldCBieSB1c2luZyBQUk9DIFNRTC4NCg0KYGBge3J9DQojcmVhZCBkYXRhIGZpbGVzIGZyb20gR2l0SHViDQpJLlAuUCA9IHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vR1VBTlRTRVJOLUtVTy93ZWJjdi9tYWluL3cwNS9pbmNvbWVfcGVyX3BlcnNvbi5jc3YiKQ0KDQpMLkUuWSA9IHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vR1VBTlRTRVJOLUtVTy93ZWJjdi9tYWluL3cwNS9saWZlX2V4cGVjdGFuY3lfeWVhcnMuY3N2IikNCg0KDQpjb3VudHJ5dG90ID0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9HVUFOVFNFUk4tS1VPL3dlYmN2L21haW4vdzA1L2NvdW50cmllc190b3RhbC5jc3YiKQ0KDQoNCnBvcHRvdCA9IHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vR1VBTlRTRVJOLUtVTy93ZWJjdi9tYWluL3cwNS9wb3B1bGF0aW9uX3RvdGFsLmNzdiIpDQoNCg0KI3RyYW5zcG9zZSBkYXRhIGZyb20gd2lkZSB0byBsb25nDQoNCklQUGxvbmcgPC0gbWVsdChzZXREVChJLlAuUCksdmFsdWUubmFtZSA9ICJpbmNvbWUiLCBpZC52YXJzID0gYygiZ2VvIiksIHZhcmlhYmxlLm5hbWUgPSAieWVhciIpDQoNCkxFWWxvbmcgPC0gbWVsdChzZXREVChMLkUuWSksdmFsdWUubmFtZSA9ICJsaWZlX2V4cGVjdGFuY3kiLCBpZC52YXJzID0gYygiZ2VvIiksIHZhcmlhYmxlLm5hbWUgPSAieWVhciIpDQoNCnBvcHRvdGxvbmcgPC0gbWVsdChzZXREVChwb3B0b3QpLHZhbHVlLm5hbWUgPSAicG9wX3NpemUiLCBpZC52YXJzID0gYygiZ2VvIiksIHZhcmlhYmxlLm5hbWUgPSAieWVhciIpDQoNCg0KIyMgcmVtb3ZlIHN0cmluZyBYDQpJUFBsb25nJHllYXI8LWdzdWIoIlgiLCIiLGFzLmNoYXJhY3RlcihJUFBsb25nJHllYXIpKQ0KTEVZbG9uZyR5ZWFyPC1nc3ViKCJYIiwiIixhcy5jaGFyYWN0ZXIoTEVZbG9uZyR5ZWFyKSkNCnBvcHRvdGxvbmckeWVhcjwtZ3N1YigiWCIsIiIsYXMuY2hhcmFjdGVyKHBvcHRvdGxvbmckeWVhcikpDQoNCg0KI21lcmdlIEluY29tZSBQZXIgUGVyc29uIGFuZCBMaWZlIEV4cGVjdGFuY3kgaW4gWWVhcnMgDQpMaWZlRXhwSW5jb20gPC0gbWVyZ2UoTEVZbG9uZywgSVBQbG9uZywgYnkgPSBjKCJnZW8iLCAieWVhciIpLA0KICAgICAgICAgICAgICAgICAgICAgIGFsbCA9IFRSVUUpDQoNCiNDcmVhdGUgZGF0YWJhc2UNCmNvbiA8LSBkYkNvbm5lY3QoZHJ2ID0gU1FMaXRlKCksDQogICAgICAgICAgICAgICAgIGRibmFtZSA9ICI6bWVtb3J5OiIpDQoNCiNzdG9yZSBzYW1wbGUgZGF0YSBpbiBkYXRhYmFzZQ0KZGJXcml0ZVRhYmxlKGNvbm4gPSBjb24sIA0KICAgICAgICAgICAgIG5hbWUgPSAiTEVZbG9uZyIsDQogICAgICAgICAgICAgdmFsdWUgPSBMRVlsb25nKQ0KDQpkYldyaXRlVGFibGUoY29ubiA9IGNvbiwgDQogICAgICAgICAgICAgbmFtZSA9ICJJUFBsb25nIiwNCiAgICAgICAgICAgICB2YWx1ZSA9IElQUGxvbmcpDQoNCmRiV3JpdGVUYWJsZShjb25uID0gY29uLCANCiAgICAgICAgICAgICBuYW1lID0gIkxpZmVFeHBJbmNvbSIsDQogICAgICAgICAgICAgdmFsdWUgPSBMaWZlRXhwSW5jb20pDQoNCmRiV3JpdGVUYWJsZShjb25uID0gY29uLCANCiAgICAgICAgICAgICBuYW1lID0gImNvdW50cnl0b3QiLA0KICAgICAgICAgICAgIHZhbHVlID0gY291bnRyeXRvdCkNCg0KZGJXcml0ZVRhYmxlKGNvbm4gPSBjb24sIA0KICAgICAgICAgICAgIG5hbWUgPSAicG9wdG90bG9uZyIsDQogICAgICAgICAgICAgdmFsdWUgPSBwb3B0b3Rsb25nKQ0KDQoNCmBgYA0KDQoNCg0KDQpgYGB7c3FsLCBjb25uZWN0aW9uID0gImNvbiIsIG91dHB1dC52YXIgPSAibGlmZTIifSANCg0KU0VMRUNUIGEuKiwgYi5yZWdpb24NCkZST00gTGlmZUV4cEluY29tIEFTIEENCkxFRlQgSk9JTiBjb3VudHJ5dG90IEFTIEINCk9OIEEuZ2VvID0gQi5uYW1lOw0KDQoNCmBgYA0KDQpgYGB7cn0NCg0KI3N0b3JlIHNhbXBsZSBkYXRhIGluIGRhdGFiYXNlDQpkYldyaXRlVGFibGUoY29ubiA9IGNvbiwgDQogICAgICAgICAgICAgbmFtZSA9ICJsaWZlMiIsDQogICAgICAgICAgICAgdmFsdWUgPSBsaWZlMikNCg0KYGBgDQoNCg0KYGBge3NxbCwgY29ubmVjdGlvbiA9ICJjb24iLCBvdXRwdXQudmFyID0gImZpbmFsIn0gDQpTRUxFQ1QgYS4qLCBiLnBvcF9zaXplDQpGUk9NIGxpZmUyIEFTIEENCkxFRlQgSk9JTiBwb3B0b3Rsb25nIEFTIEINCk9OIEEuZ2VvID0gQi5nZW8gQU5EIEEueWVhciA9IEIueWVhciA7DQpgYGANCg0KYGBge3J9DQojIHdyaXRlIGZpbmFsIGRhdGEgdG8gY3N2IGZpbGUNCndyaXRlLmNzdih4ID0gZmluYWwsIGZpbGUgPSAiZmluYWwuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KDQoNCmBgYHtyfQ0KDQojIHJlYWQgZmluYWwgZmlsZQ0KZmluYWwgPSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0dVQU5UU0VSTi1LVU8vd2ViY3YvbWFpbi93MDUvZmluYWwuY3N2IikNCg0KDQpkYXRhMjAxNSA8LSBmaWx0ZXIoZmluYWwseWVhcj09MjAxNSkgICMgY3JlYXRlIDIwMTVkYXRhDQoNCmRhdGEyMDE1JHNpemUwMDAgPC0gZGF0YTIwMTUkcG9wX3NpemUvMjAwMDAwMDAgDQpgYGANCg0KDQojIyBEZXNjcmlwdGl2ZSBTdHVkeSBQdXJwb3NlICYgVmFyaWFibGVzIFJlbGF0aW9uc2hpcCANCg0KVGhlIHN0dWR5IGZvY3VzIG9uIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUgYW5kIGxpZmUgZXhwZWN0YW5jeSBhY3Jvc3MgcmVnaW9uIGluIDIwMTUuIFNlY29uZGFyeSB1bmRlcnN0YW5kaW5nIG9mIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUgYW5kIGxpZmUgZXhwZWN0YW5jeSBvdmVyIHllYXIgaW4gZGlmZmVyZW50IHJlZ2lvbnMuIFRoZXJlIGFyZSA3IHZhcmlhYmxlcyBpbiBmaW5hbCBkYXRhc2V0LiANCg0KDQoNCi0gZ2VvIDogZ2VvZ3JhcGh5DQotIHBvcF9zaXplIDogcG9wdWxhdGlvbiBzaXplDQotIHNpemUwMDAgOiBlcXVpdmFsZW50IHJhdGlvIHRvIHBvcHVsYXRpb24gc2l6ZQ0KDQpUaGUgYmVsb3cgaXMgdGhlIGRhdGEgdGFibGUgZm9yIDIwMTUuDQoNCmBgYHtyIGV2YWw9cmVxdWlyZU5hbWVzcGFjZSgiRFQiLCBxdWlldGx5PVRSVUUpLCBlY2hvPUZBTFNFfQ0KRFQ6OmRhdGF0YWJsZSgoZGF0YTIwMTUpLCBmaWxsQ29udGFpbmVyID0gRkFMU0UsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSA2KSkNCg0KDQpgYGANCg0KDQoNCg0KDQoNCmBgYHtyfQ0Kc3VtbWFyeShkYXRhMjAxNSkNCg0KYGBgDQoNClBlb3BsZSB3aXRoIGEgbWF4aW11bSBpbmNvbWUgb2YgMTIwMDAwIGFuZCBhIG1pbmltdW0gaW5jb21lIG9mIDYyMyBpbiAyMDE1LiBBbHNvLCBpbiAyMDE1LCBwZW9wbGUncyBsaWZlIGV4cGVjdGFuY3kgaW5kZXggcmFuZ2VkIGZyb20gYSBoaWdoIG9mIDgzLjggdG8gYSBsb3cgb2YgNDkuNi4NCg0KIyMgICBUaGUgRGlzdHJpYnVpdGlvbiBvZiBSZWdpb24gaW4gMjAxNQ0KDQpBc2lhIGhhcyB0aGUgaGlnaGVzdCBwZXJjZW50YWdlIG9mIHRoZSB3b3JsZCdzIHBvcHVsYXRpb24gKDI4LjUlKSwgd2l0aCBhIHRvdGFsIG9mIDUxIGNvdW50cmllcy4gT2NlYW5pYSBoYXMgdGhlIGxvd2VzdCBwZXJjZW50YWdlIG9mIHRoZSB3b3JsZCdzIHBvcHVsYXRpb24gKDcuMjYlKSwgd2l0aCBhIHRvdGFsIG9mIDEzIGNvdW50cmllcy4NCg0KYGBge3J9DQpwaWVkYXRhIDwtIGZpbHRlcihkYXRhMjAxNSwhaXMubmEocmVnaW9uKSkNCg0KcGllZGF0YWYgPSBkYXRhLmZyYW1lKGNhdGUgPWFzLnZlY3Rvcih1bmlxdWUocGllZGF0YSRyZWdpb24pKSwgDQogICAgICAgICAgICAgICAgICAgICBmcmVxID0gYXMudmVjdG9yKHRhYmxlKHBpZWRhdGEkcmVnaW9uKSkpDQoNCiMgZGVmaW5lIGEgY29sb3IgdmVjdG9yDQpjb2xvcnMgPC0gYygncmdiKDIxMSw5NCw5NiknLCAncmdiKDEyOCwxMzMsMTMzKScsICdyZ2IoMTQ0LDEwMywxNjcpJykNCiMgbWFrZSBhIHBpZSBjaGFydA0KcGxvdF9seShwaWVkYXRhZiwgDQogICAgICAgIGxhYmVscyA9IH5jYXRlLCANCiAgICAgICAgdmFsdWVzID0gfmZyZXEsIA0KICAgICAgICB0eXBlID0gJ3BpZScsDQogICAgICAgIHRleHRwb3NpdGlvbiA9ICdpbnNpZGUnLA0KICAgICAgICB0ZXh0aW5mbyA9ICdsYWJlbCArIHBlcmNlbnQnLA0KICAgICAgICBpbnNpZGV0ZXh0Zm9udCA9IGxpc3QoY29sb3IgPSAnI0ZGRkZGRicpLA0KICAgICAgICAjaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9ycyA9IGNvbG9ycywNCiAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICcjRkZGRkZGJywgd2lkdGggPSAxKSksDQogICAgICAgICAgICAgICAgICAgICAgI1RoZSAncHVsbCcgYXR0cmlidXRlIGNhbiBhbHNvIGJlIHVzZWQgdG8gY3JlYXRlIHNwYWNlIGJldHdlZW4gdGhlIHNlY3RvcnMNCiAgICAgICAgc2hvd2xlZ2VuZCA9IFRSVUUpICU+JSANCiAgICAgICAgIGxheW91dCh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgUmVnaW9uIGluIDIwMTUnLA0KICAgICAgICAgICAgICAgIHhheGlzID0gbGlzdChzaG93Z3JpZCA9IEZBTFNFLCB6ZXJvbGluZSA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd3RpY2tsYWJlbHMgPSBGQUxTRSksDQogICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHNob3dncmlkID0gRkFMU0UsIHplcm9saW5lID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93dGlja2xhYmVscyA9IEZBTFNFKSwNCiAgICAgICAgICAgICAgICAgICAgICAjIyBtYXJnaW4gb2YgdGhlIHBsb3QNCiAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgbCA9IDEwMCwNCiAgICAgICAgICAgICAgdCA9IDEyMCwNCiAgICAgICAgICAgICAgciA9IDUwDQogICAgICApKQ0KYGBgDQoNCiMjICAgVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIEluY29tZSBhbmQgTGlmZSBFeHBlY3RhbmN5IGFjcm9zcyBSZWdpb24gaW4gMjAxNQ0KDQoNCk1vc3QgcGVvcGxlIGluIHRoZSBFdXJvcGVhbiByZWdpb24gaGF2ZSBoaWdoZXIgaW5jb21lcyBhbmQgaGlnaGVyIGxldmVscyBvZiBsaWZlIGV4cGVjdGFuY3kuIEFuZCBtb3N0IHBlb3BsZSBpbiB0aGUgQWZyaWNhbiByZWdpb24gaGF2ZSBsb3dlciBpbmNvbWVzIGFuZCBsb3dlciBsZXZlbHMgb2YgbGlmZSBleHBlY3RhbmN5Lg0KDQoNCmBgYHtyfQ0KDQpwbG90X2x5KA0KICAgIGRhdGEgPSBkYXRhMjAxNSwNCiAgICB4ID0gfmluY29tZSwgICMgSG9yaXpvbnRhbCBheGlzIA0KICAgIHkgPSB+bGlmZV9leHBlY3RhbmN5LCAgICMgVmVydGljYWwgYXhpcyANCiAgICBjb2xvciA9IH5mYWN0b3IocmVnaW9uKSwgICMgbXVzdCBiZSBhIG51bWVyaWMgZmFjdG9yDQogICAgDQogICAgI3RleHQgPSB+U3BlY2llcywNCiAgICB0ZXh0ID0gfnBhc3RlKCJjb3VudHJ5IG5hbWU6ICIsIGdlbywNCiAgICAgICAgICAgICAgICAgICAiPGJyPnBvcHVsYXRpb24gc2l6ZTogIiwgcG9wX3NpemUsDQogICAgICAgICAgICAgICAgICAgIjxicj5yZWdpb246ICIsIHJlZ2lvbiksIA0KICAgICAjIFNob3cgdGhlIHNwZWNpZXMgaW4gdGhlIGhvdmVyIHRleHQNCiAgICAgIyMgdXNpbmcgdGhlIGZvbGxvd2luZyBob3ZlcnRlbXBsYXRlKCkgdG8gYWRkIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUNCiAgICAgIyMgVHdvIG51bWVyaWNhbCB2YXJpYWJsZXMgdG8gdGhlIGhvdmVyIHRleHQuDQogICAgICMjIyBVc2UgdGhlIGZvbGxvd2luZyBob3ZlciB0ZW1wbGF0ZSB0byBkaXNwbGF5IG1vcmUgaW5mb3JtYXRpb24NCiAgICAgaG92ZXJ0ZW1wbGF0ZSA9IHBhc3RlKCc8aT48Yj5saWZlIGV4cGVjdGFuY3k8Yj48L2k+OiAle3l9JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+PGI+aW5jb21lPC9iPjogICV7eH0nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj48Yj4le3RleHR9PC9iPicpLA0KICAgICBhbHBoYSAgPSAwLjYsDQogICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IH5zaXplMDAwLCBzaXplcmVmID0gLjA1LCBzaXplbW9kZSA9ICdhcmVhJyApLA0KICAgICB0eXBlID0gInNjYXR0ZXIiLA0KICAgICBtb2RlID0gIm1hcmtlcnMiLA0KICAgICAjIyBncmFwaGljIHNpemUNCiAgICAgd2lkdGggPSA3MDAsDQogICAgIGhlaWdodCA9IDUwMCkgJT4lDQogICAgbGF5b3V0KCAgDQogICAgICAjIyMgVGl0bGUgDQogICAgICB0aXRsZSA9bGlzdCh0ZXh0ID0gIkluY29tZSB2cyBMaWZlIEV4cGVjdGFuY3kgaW4gMjAxNSIsIA0KICAgICAgICAgICAgICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsICAjIEhUTUwgZm9udCBmYW1pbHkgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMTgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAicmVkIikpLCANCiAgICAgICMjIyBsZWdlbmQNCiAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAncmVnaW9uJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQgPSBsaXN0KGZhbWlseSA9ICJDb3VyaWVyIE5ldyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJncmVlbiIpKSwNCiAgICAgICAgICAgICAgICAgICAgYmdjb2xvciA9ICJpdm9yeSIsDQogICAgICAgICAgICAgICAgICAgIGJvcmRlcmNvbG9yID0gIm5hdnkiLA0KICAgICAgICAgICAgICAgICAgICBncm91cGNsaWNrID0gInRvZ2dsZWdyb3VwIiwgICMgb25lIG9mICAidG9nZ2xlaXRlbSIgQU5EICJ0b2dnbGVncm91cCIuDQogICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uID0gInYiICAjIFNldHMgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBsZWdlbmQuDQogICAgICAgICAgICAgICAgICAgICksDQogICAgICAjIyBtYXJnaW4gb2YgdGhlIHBsb3QNCiAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgIGIgPSAxMDAsDQogICAgICAgICAgICAgIGwgPSAxMDAsDQogICAgICAgICAgICAgIHQgPSA1MCwNCiAgICAgICAgICAgICAgciA9IDUwDQogICAgICApLA0KICAgICAgIyMgQmFja2dyb3VuZA0KICAgICAgcGxvdF9iZ2NvbG9yID0nI2Y3ZjdmNycsIA0KICAgICAgIyMgQXhlcyBsYWJlbHMNCiAgICAgICAgICAgICB4YXhpcyA9IGxpc3QoIA0KICAgICAgICAgICAgICAgICAgICB0aXRsZT1saXN0KHRleHQgPSAnSW5jb21lJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAnQXJpYWwnKSksDQogICAgICAgICAgICAgICAgICAgIHplcm9saW5lY29sb3IgPSAncmVkJywgDQogICAgICAgICAgICAgICAgICAgIHplcm9saW5ld2lkdGggPSAyLCANCiAgICAgICAgICAgICAgICAgICAgZ3JpZGNvbG9yID0gJ3doaXRlJyksIA0KICAgICAgICAgICAgeWF4aXMgPSBsaXN0KCANCiAgICAgICAgICAgICAgICAgICAgdGl0bGU9bGlzdCh0ZXh0ID0gJ0xpZmUgRXhwZWN0YW5jeScsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gJ0FyaWFsJykpLA0KICAgICAgICAgICAgICAgICAgICB6ZXJvbGluZWNvbG9yID0gJ3B1cnBsZScsIA0KICAgICAgICAgICAgICAgICAgICB6ZXJvbGluZXdpZHRoID0gMiwgDQogICAgICAgICAgICAgICAgICAgIGdyaWRjb2xvciA9ICd3aGl0ZScpLA0KICAgICAgICMjIGFubm90YXRpb25zDQogICAgICAgYW5ub3RhdGlvbnMgPSBsaXN0KCAgDQogICAgICAgICAgICAgICAgICAgICB4ID0gMC41LCAgICMgYmV0d2VlbiAwIGFuZCAxLiAwID0gbGVmdCwgMSA9IHJpZ2h0DQogICAgICAgICAgICAgICAgICAgICB5ID0gMS41LCAgICMgYmV0d2VlbiAwIGFuZCAxLCAwID0gYm90dG9tLCAxID0gdG9wDQogICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChzaXplID0gMTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJkYXJrcmVkIiksICAgDQogICAgICAgICAgICAgICAgICB0ZXh0ID0gIlRoZSBwb2ludCBzaXplIGlzIHByb3BvcnRpb25hbCB0byB0aGUgcG9wdWxhdGlvbiBzaXplIiwgICANCiAgICAgICAgICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCAgIyAiY29udGFpbmVyIiBzcGFucyB0aGUgZW50aXJlIGB3aWR0aGAgb2YgdGhlIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICBsb3QuICJwYXBlciIgcmVmZXJzIHRvIHRoZSB3aWR0aCBvZiB0aGUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgIHBsb3R0aW5nIGFyZWEgb25seS4geXJlZiA9ICJwYXBlciIsICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAgc2FtZSBhcyB4cmVmLg0KICAgICAgICAgICAgICAgeGFuY2hvciA9ICJjZW50ZXIiLCAjICBob3Jpem9udGFsIGFsaWdubWVudCB3aXRoIHJlc3BlY3QgdG8gaXRzIHggcG9zaXRpb24NCiAgICAgICAgICAgICAgIHlhbmNob3IgPSAiYm90dG9tIiwgIyAgc2ltaWxhciB0byB4YW5jaG9yICANCiAgICAgICAgICAgICBzaG93YXJyb3cgPSBGQUxTRSkNCiAgICANCiAgICAgDQogICAgDQogICAgKSANCg0KYGBgDQojIyAgIFRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBJbmNvbWUgYW5kIExpZmUgRXhwZWN0YW5jeSBhY3Jvc3MgUmVnaW9uIG92ZXIgdGhlIHllYXJzICANCg0KVGhlIGxpZmUgZXhwZWN0YW5jeSBvZiBwZW9wbGUgaW4gdGhlIGFsbCByZWdpb25zIGhhcyBpbmNyZWFzZWQgd2l0aCBlYWNoIHBhc3NpbmcgeWVhci4gSW4gMTgwMCwgbW9zdCBvZiBFdXJvcGUgaGFkIGEgaGlnaGVyIGxldmVsIG9mIGxpZmUgZXhwZWN0YW5jeS4gSG93ZXZlciwgaW4gMjAxOCwgaGlnaGVyIGxldmVscyBvZiBsaWZlIGV4cGVjdGFuY3kgbWF5IGNvbWUgZnJvbSAgbXVsdGlwbGUgcmVnaW9uYWwgb2YgY291bnRyeS4gQXMgY2FuIGJlIHNlZW4gZnJvbSB0aGUgZmlndXJlLCB0aGVyZSBpcyBhIHBvc2l0aXZlIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUgYW5kIGxldmVscyBvZiBsaWZlIGV4cGVjdGFuY3kgYWNyb3NzIHJlZ2lvbnMuDQpgYGB7cn0gDQoNCnBhbC5JQk0gPC0gYygiIzMzMjI4OCIsICIjMTE3NzMzIiwgIiMwMDcyQjIiLCIjRDU1RTAwIiwgIiM4ODIyNTUiKQ0KcGFsLklCTSA8LSBzZXROYW1lcyhwYWwuSUJNLCBjKCJBc2lhIiwgIkV1cm9wZSIsICJBZnJpY2EiLCAiQW1lcmljYXMiLCAiT2NlYW5pYSIpKQ0KDQpkZiA8LSBmaWx0ZXIoZmluYWwsIWlzLm5hKHJlZ2lvbikpDQoNCiNkZiA8LSBmaW5hbCANCmZpZyA8LSBkZiAlPiUNCiAgcGxvdF9seSgNCiAgICB4ID0gfmluY29tZSwgDQogICAgeSA9IH5saWZlX2V4cGVjdGFuY3ksIA0KICAgIHNpemUgPSB+KDIqbG9nKHBvcF9zaXplKS0xMSleMiwNCiAgICBjb2xvciA9IH5yZWdpb24sIA0KICAgIGNvbG9ycyA9IHBhbC5JQk0sICAgIyBjdXN0b20gY29sb3JzDQogICAgI21hcmtlciA9IGxpc3Qoc2l6ZSA9IH4obG9nKHBvcCktMTApLCAgc2l6ZW1vZGUgPSAnYXJlYScpLA0KICAgIGZyYW1lID0gfnllYXIsICAgICAgIyB0aGUgdGltZSB2YXJpYWJsZSB0bw0KICAgICMgdG8gZGlzcGxheSBpbiB0aGUgaG92ZXINCiAgICB0ZXh0ID0gfnBhc3RlKCJDb3VudHJ5OiIsIGdlbywNCiAgICAgICAgICAgICAgICAgICI8YnI+UmVnaW9uOiIsIHJlZ2lvbiwNCiAgICAgICAgICAgICAgICAgICI8YnI+WWVhcjoiLCB5ZWFyLA0KICAgICAgICAgICAgICAgICAgIjxicj5MaWZlRXhwOiIsIGxpZmVfZXhwZWN0YW5jeSwNCiAgICAgICAgICAgICAgICAgICI8YnI+UG9wOiIsIHBvcF9zaXplKSwNCiAgICBob3ZlcmluZm8gPSAidGV4dCIsDQogICAgdHlwZSA9ICdzY2F0dGVyJywNCiAgICBtb2RlID0gJ21hcmtlcnMnDQogICkNCmZpZyA8LSBmaWcgJT4lIGxheW91dCgNCiAgICB4YXhpcyA9IGxpc3QoDQogICAgICB0eXBlID0gImxvZyINCiAgICApLA0KICAgIA0KICAgICAgdGl0bGUgPWxpc3QodGV4dCA9ICJJbmNvbWUgdnMgTGlmZSBFeHBlY3RhbmN5IG92ZXIgdGhlIHllYXJzIiwgDQogICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiwgICMgSFRNTCBmb250IGZhbWlseSAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxOCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJyZWQiKSksDQogICAgDQogICAgICB4YXhpcyA9IGxpc3QoIA0KICAgICAgICAgICAgICAgICAgICB0aXRsZT1saXN0KHRleHQgPSAnSW5jb21lJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAnQXJpYWwnKSksDQogICAgICAgICAgICAgICAgICAgIHplcm9saW5lY29sb3IgPSAncmVkJywgDQogICAgICAgICAgICAgICAgICAgIHplcm9saW5ld2lkdGggPSAyLCANCiAgICAgICAgICAgICAgICAgICAgZ3JpZGNvbG9yID0gJ3doaXRlJyksIA0KICAgICAgICAgICAgeWF4aXMgPSBsaXN0KCANCiAgICAgICAgICAgICAgICAgICAgdGl0bGU9bGlzdCh0ZXh0ID0gJ0xpZmUgRXhwZWN0YW5jeScsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gJ0FyaWFsJykpLA0KICAgICAgICAgICAgICAgICAgICB6ZXJvbGluZWNvbG9yID0gJ3B1cnBsZScsIA0KICAgICAgICAgICAgICAgICAgICB6ZXJvbGluZXdpZHRoID0gMiwgDQogICAgICAgICAgICAgICAgICAgIGdyaWRjb2xvciA9ICd3aGl0ZScpDQogICkNCg0KZmlnDQpgYGANCg0KDQo=